package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

func main() {
	//获取服务器线程数
	num := runtime.NumCPU()
	//设置运行线程数
	runtime.GOMAXPROCS(num)
	fmt.Println("cpu",num)

	//group()
	//selectR()

	//chan简单使用
	//intChan := make(chan int, 10)
	//go write(intChan)
	//go read(intChan)
	//time.Sleep(time.Second * 5)
}

/*
等待所有协程完成会执行，预备跑
*/
func group(){
	var wg sync.WaitGroup
	wg.Add(5)

	for i := 0; i < 5; i = i + 1 {
		//wg.Add(1)
		go func(n int) {
			defer wg.Done() //等价于 defer wg.Add(-1)
			time.Sleep(2)
			fmt.Println(n)
		}(i)
	}
	wg.Wait()
	fmt.Println("跑")
}

/*
相互通信（异步）
1.全局变量和锁同步
2.Channel(先进先出、线程安全、 channel是有类型的)

声明
var 变量名 chan 类型
var test chan int
var test chan string
var test chan map[string]string
var test chan stu
var test chan *stu

初始化
var test1 = chan int
test1 = make(chan int) //只能存一个参数
test2 = make(chan int, 10) //可以存10个参数
*/
func write(ch chan int) {
	for i := 0; i < 100; i++ {
		ch <- i
		fmt.Println("put data: ", i)
	}
}

func read(ch chan int) {
	for {
		var b int
		b = <-ch
		fmt.Println(b)
		time.Sleep(time.Second)
	}
}

/*
chan关闭
close(ch)
可以继续取数据，不能写数据
var readChan <-chan int 只读chan的声明
var writeChan chan <- int  只写chan的声明
*/
func closeR(){
	var ch chan int
	ch = make(chan int, 10)

	for i := 0; i < 10; i++ {
		ch <- i
	}
	close(ch)
	for {
		var b int
		b, ok := <-ch
		if ok == false { //判断chan是否已关闭，且没有数据
			fmt.Println("chan is close")
			break
		}
		fmt.Println(b)
	}
}

/*
select
一个循环监听多个channel
*/
func selectR()  {
	var ch chan int
	ch = make(chan int, 10)
	ch2 := make(chan int, 10)
	go func() {
		var i int
		for {
			ch <- i
			time.Sleep(time.Second)
			ch2 <- i * i
			time.Sleep(time.Second)
			i++
		}
	}()

	for {
		select {
		case v := <-ch:
			fmt.Println(v)
		case v := <-ch2:
			fmt.Println(v)
		case <-time.After(time.Second):   //定时器，1秒钟后执行
			fmt.Println("get data timeout")
			time.Sleep(time.Second)
		}
		// var b int
		// b = <-ch
		// fmt.Println(b)
	}
}
